#include <iostream>
#include "tcpclient.h"
#include "userbuffer.h"
#include "controller.h"
#include "afn/afn0d.h"

static Loger log;

bool init(bool slave=true, uint8_t delay=3)
{
	sMtInit init;

	init.eRole = slave ? MT_ROLE_CONTOR : MT_ROLE_MASTER;
	init.ucPermitDelayMinutes = delay;

	return eMtInit(&init)==MT_OK;
}
void test_buffer(void)
{
	UserBuffer buf;

	buf.setRegion	("4301"				).
		setTerminal	(256				).
		setMac		(0					).
		setTeam		(0					).
		setDir		(MT_DIR_S2M			).
		setPrm		(MT_PRM_PASIVE		).
		setTpv		(false				).
		setPos		(MT_POS_SIGLE		).
		setCon		(false				).
		setNum		(1					).
		setApp		(0					).
		setPn		(0					).
		setAfn		(AFN_00_CONF		).
		setCmd		(CMD_AFN_0_F1_ALL_OK).
		packup();

	buf.setSeq(2					).
		setAfn(AFN_02_LINK			).
		setCmd(CMD_AFN_2_F1_LOG_IN	).
		setPrm(MT_PRM_ACTIVE		).
		packup();

	buf.setSeq(3						).
		setAfn(AFN_02_LINK				).
		setCmd(CMD_AFN_2_F3_HEART_BEAT	).
		setPrm(MT_PRM_ACTIVE			).
		packup();

	UserBuffer& data = buf;

    data.m_data.sData[0].uApp.sTmlCurvePower.sTd_c.sT.ucYY = 12;
    data.m_data.sData[0].uApp.sTmlCurvePower.sTd_c.sT.ucMM = 6;
    data.m_data.sData[0].uApp.sTmlCurvePower.sTd_c.sT.ucDD = 19;
    data.m_data.sData[0].uApp.sTmlCurvePower.sTd_c.sT.ucHH = 18;
    data.m_data.sData[0].uApp.sTmlCurvePower.sTd_c.sT.ucmm = 46;
    data.m_data.sData[0].uApp.sTmlCurvePower.sTd_c.ucM = 255;
    data.m_data.sData[0].uApp.sTmlCurvePower.sTd_c.ucN = 6;

    data.m_data.sData[0].uApp.sTmlCurvePower.dEnergy[0] = 1234.5678;
    data.m_data.sData[0].uApp.sTmlCurvePower.dEnergy[1] = 9999.9999;
    data.m_data.sData[0].uApp.sTmlCurvePower.dEnergy[2] = 0.0001;
    data.m_data.sData[0].uApp.sTmlCurvePower.dEnergy[3] = 6666.5555;
    data.m_data.sData[0].uApp.sTmlCurvePower.dEnergy[4] = 8523.9874;
    data.m_data.sData[0].uApp.sTmlCurvePower.dEnergy[5] = 3000.0;

	buf.setSeq(4								).
		setAfn(AFN_0D_ASK2						).
		setCmd(CMD_AFN_D_F218_COLOR_YAWP_CURVE	).
		setPrm(MT_PRM_PASIVE					).
		packup();

	buf.setSeq(5							).
		setAfn(AFN_0D_ASK2					).
		setCmd(CMD_AFN_D_F97_CURVE_FRTH_HAVE).
		setPrm(MT_PRM_PASIVE				).
		packup();
}
void handle_AFN0(Controller& controller)
{
}
void handle_AFN1(Controller& controller)
{
}
void handle_AFN2(Controller& controller)
{
}
void handle_AFN3(Controller& controller)
{
}
void handle_AFN4(Controller& controller)
{
	controller.confirmAll();
}
void handle_AFN5(Controller& controller)
{
	controller.confirmAll();
}
void handle_AFN6(Controller& controller)
{
}
void handle_AFN7(Controller& controller)
{
}
void handle_AFN8(Controller& controller)
{
}
void handle_AFN9(Controller& controller)
{
}
void handle_AFNA(Controller& controller)
{
}
void handle_AFNB(Controller& controller)
{
}
void handle_AFNC(Controller& controller)
{
}
void handle_AFND(Controller& controller)
{
	static AFN0D_Handler handler;

	handler.handle(controller);
}
void handle_AFNE(Controller& controller)
{
}
void handle_AFNF(Controller& controller)
{
}
void handle_AFN10(Controller& controller)
{
}
void handle_packet(Controller& controller)
{
	if(controller.recvbuf.unpack())
	{
		log << controller.recvbuf.toStringU();
		UserBuffer& b = controller.recvbuf;

		switch(b.getAfn())
		{
			case 0x00: handle_AFN0(controller); break;
			case 0x01: handle_AFN1(controller); break;
			case 0x02: handle_AFN2(controller); break;
			case 0x03: handle_AFN3(controller); break;
			case 0x04: handle_AFN4(controller); break;
			case 0x05: handle_AFN5(controller); break;
			case 0x06: handle_AFN6(controller); break;
			case 0x07: handle_AFN7(controller); break;
			case 0x08: handle_AFN8(controller); break;
			case 0x09: handle_AFN9(controller); break;
			case 0x0A: handle_AFNA(controller); break;
			case 0x0B: handle_AFNB(controller); break;
			case 0x0C: handle_AFNC(controller); break;
			case 0x0D: handle_AFND(controller); break;
			case 0x0E: handle_AFNE(controller); break;
			case 0x0F: handle_AFNF(controller); break;
			case 0x10: handle_AFNF(controller); break;
		}
	}
}
int main(int argc, char **argv)
{
	Controller controller;
	UserBuffer &buf = controller.sendbuf;

	init();
	//test_buffer();

	if(controller.connect(argc > 1 ? argv[1] : "124.232.137.226:2028") == false)
	{
		perror("connect");
		return -1;
	}
	controller.region = "4301";
	controller.terminal = 256;
	controller.macaddr  = 0;
	controller.team		= 0;
	controller.seq		= 0;

	buf.setRegion	("4301"				).
		setTerminal	(256				).
		setMac		(0					).
		setTeam		(0					).
		setDir		(MT_DIR_S2M			).
		setPrm		(MT_PRM_PASIVE		).
		setTpv		(false				).
		setPos		(MT_POS_SIGLE		).
		setCon		(false				).
		setNum		(1					).
		setApp		(0					).
		setPn		(0					).
		setAfn		(AFN_00_CONF		).
		setCmd		(CMD_AFN_0_F1_ALL_OK).
		packup();

	buf.setSeq(0					).
		setAfn(AFN_02_LINK			).
		setCmd(CMD_AFN_2_F1_LOG_IN	).
		setPrm(MT_PRM_ACTIVE		).
		packup();

	if(controller.doSendWork() == false)
	{
		printf("doSendWork() failed!\n");
		return -1;
	}
	cout << "T: " + controller.sendbuf.toStringF() << endl;;
	log  << "T: " + controller.sendbuf.toStringF();

	while(1)
	{
		if(controller.doRecvWork() )
		{
			if( controller.checkRecvBuffer() )
			{
				cout << "R: " + controller.recvbuf.toStringF() << endl;
				log << "R: " + controller.recvbuf.toStringF();
				handle_packet(controller);
				controller.recvbuf.clear();
			}
		}
		controller.checkRecvTimeout();
		controller.sendHeatbeat();
		usleep(100);
		fflush(stdout);
	}

	return 0;
}
